package com.yupi.yu_picture.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.yu_picture.constant.UserConstant;
import com.yupi.yu_picture.exception.BusinessException;
import com.yupi.yu_picture.exception.ErrorCode;
import com.yupi.yu_picture.exception.ThrowUtil;
import com.yupi.yu_picture.manager.auth.model.StpKit.java.StpKit;
import com.yupi.yu_picture.mapper.UserMapper;
import com.yupi.yu_picture.model.dto.user.UserAddRequest;
import com.yupi.yu_picture.model.dto.user.UserQueryRequest;
import com.yupi.yu_picture.model.entity.User;
import com.yupi.yu_picture.model.enums.UserRoleEnum;
import com.yupi.yu_picture.model.vo.LoginUserVO;
import com.yupi.yu_picture.model.vo.UserVO;
import com.yupi.yu_picture.service.UserService;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.yupi.yu_picture.constant.UserConstant.USER_LOGIN_STATE;

/**
* @author 41722
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2025-03-21 20:12:50
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    @Override
    public Long UserRegister(String userAccount, String userPassword, String checkPassword) {
        if (StrUtil.hasBlank(userAccount,userPassword,checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if (userAccount.length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账户长度过短");
        }
        if (userPassword.length()<8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码过短");
        }
        if (!userPassword.equals(checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次输入密码不一致");
        }
        //查询是否有相同用户
        Long count = this.baseMapper.selectCount(new QueryWrapper<User>().eq("userAccount", userAccount));
        if (count>0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账户重复");
        }

        //加密：
        String encryptPassword = getEncryptPassword(userPassword);
        //插入数据：
        User user = new User();

        user.setUserAccount(userAccount);
        user.setUserPassword(encryptPassword);
        user.setUserName("无名");
        user.setUserRole(UserRoleEnum.User.getValue());

        boolean saveResult = this.save(user);
        if (!saveResult){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"数据库错误");
        }
        //主键反注
        return user.getId();
    }

    @Override
    public String getEncryptPassword(String userPassword) {
        //盐值,混淆密码
        final String SALT="yupi";
        return DigestUtils.md5DigestAsHex((userPassword+SALT).getBytes());
    }

    @Override
    public LoginUserVO UserLogin(String userAccount, String userPassword, HttpServletRequest request) {
        ThrowUtil.throwIf(StrUtil.hasBlank(userAccount,userPassword),ErrorCode.PARAMS_ERROR,"参数为空");
        ThrowUtil.throwIf(userAccount.length()<4,ErrorCode.PARAMS_ERROR,"账号错误");
        ThrowUtil.throwIf(userPassword.length()<4,ErrorCode.PARAMS_ERROR,"密码错误");

        //得到加密后的密码
        String encryptPassword = getEncryptPassword(userPassword);
        User user = this.baseMapper.selectOne(new QueryWrapper<User>().eq("userAccount", userAccount)
                                                                      .eq("userPassword", encryptPassword));
        ThrowUtil.throwIf(user==null,ErrorCode.PARAMS_ERROR,"用户名不存在或密码错误");

        //记录用户登录态
        request.getSession().setAttribute(USER_LOGIN_STATE,user);
        StpKit.SPACE.login(user.getId());
        StpKit.SPACE.getSession().set(USER_LOGIN_STATE,user);
        return this.getLoginUserVo(user);
    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(USER_LOGIN_STATE);
        if (user==null || user.getId()==null){
           throw  new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        //此处为了保证获取到的数据始终是最新的，先从 Session 中获取登录用户的 id，然后从数据库中查询最新的结果
        //之前保存的用户信息只是那时候的，有可能后面进行了修改，要根据用户id从数据库中查最新的数据
        Long userId = user.getId();
        User CurrentUser = this.getById(userId);
        if (CurrentUser==null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return CurrentUser;
    }

    //将用户信息脱敏并返回；
    @Override
    public  LoginUserVO getLoginUserVo(User user){
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user,loginUserVO);
        return loginUserVO;
    }

    @Override
    public boolean userLogout(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(USER_LOGIN_STATE);
        if (user==null || user.getId()==null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR,"未登录");
        }
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return true;
    }

    @Override
    public UserVO getUserVo(User user) {
        if (user==null){
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);
        return userVO;
    }

    @Override
    public List<UserVO> getListUserVo(List<User> userList) {
        if (CollUtil.isEmpty(userList)){
            return new ArrayList<>();
        }
        return userList.stream().map(this::getUserVo).collect(Collectors.toList());
    }

    @Override
    public QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest) {
        ThrowUtil.throwIf(userQueryRequest==null,ErrorCode.PARAMS_ERROR);
        Long id = userQueryRequest.getId();
        String userName = userQueryRequest.getUserName();
        String userAccount = userQueryRequest.getUserAccount();
        String userProfile = userQueryRequest.getUserProfile();
        String userRole = userQueryRequest.getUserRole();
        String sortField = userQueryRequest.getSortField();
        String sortOrder = userQueryRequest.getSortOrder();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq(ObjUtil.isNotNull(id),"id",id);
        userQueryWrapper.eq(ObjUtil.isNotNull(userRole),"userRole",userRole);
        userQueryWrapper.like(StrUtil.isNotBlank(userAccount), "userAccount", userAccount);
        userQueryWrapper.like(StrUtil.isNotBlank(userName), "userName", userName);
        userQueryWrapper.like(StrUtil.isNotBlank(userProfile), "userProfile", userProfile);
        userQueryWrapper.orderBy(StrUtil.isNotBlank(sortField),sortOrder.equals("ascend"),sortField);
        return userQueryWrapper;
    }

    @Override
    public boolean isAdmin(User user) {
        return user!=null && user.getUserRole().equals(UserConstant.ADMIN_ROLE);
    }

}




